









----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    16:24:02 09/10/2012 
-- Design Name: 
-- Module Name:    MIPS_SC_PROCESSOR - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library WORK;
use WORK.MIPS_CONSTANT_PKG.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity processor is
	generic  (
		MEM_ADDR_BUS	: integer	:= 32;
		MEM_DATA_BUS	: integer	:= 32 
		);
	port(	
		clk : in STD_LOGIC;
		reset					: in STD_LOGIC;
		processor_enable	: in  STD_LOGIC;
		imem_address 		: out  STD_LOGIC_VECTOR (MEM_ADDR_BUS-1 downto 0);
		imem_data_in 		: in  STD_LOGIC_VECTOR (MEM_DATA_BUS-1 downto 0);
		dmem_data_in 		: in  STD_LOGIC_VECTOR (MEM_DATA_BUS-1 downto 0);
		dmem_address 		: out  STD_LOGIC_VECTOR (MEM_ADDR_BUS-1 downto 0);
		dmem_address_wr	: out  STD_LOGIC_VECTOR (MEM_ADDR_BUS-1 downto 0);
		dmem_data_out		: out  STD_LOGIC_VECTOR (MEM_DATA_BUS-1 downto 0);
		dmem_write_enable	: out  STD_LOGIC
	);
end processor;

architecture Behavioral of processor is
	
	component register_file is
	port(
			CLK 			:	in	STD_LOGIC;				
			RESET			:	in	STD_LOGIC;				
			RW				:	in	STD_LOGIC;				
			RS_ADDR 		:	in	STD_LOGIC_VECTOR (RADDR_BUS-1 downto 0); 
			RT_ADDR 		:	in	STD_LOGIC_VECTOR (RADDR_BUS-1 downto 0); 
			RD_ADDR 		:	in	STD_LOGIC_VECTOR (RADDR_BUS-1 downto 0);
			WRITE_DATA	:	in	STD_LOGIC_VECTOR (DDATA_BUS-1 downto 0); 
			RS				:	out	STD_LOGIC_VECTOR (DDATA_BUS-1 downto 0);
			RT				:	out	STD_LOGIC_VECTOR (DDATA_BUS-1 downto 0)
	);
	end component register_file;
	
	component alu is
	generic (N :NATURAL := 32); 
	port(
		X			: in STD_LOGIC_VECTOR(N-1 downto 0);
		Y			: in STD_LOGIC_VECTOR(N-1 downto 0);
		ALU_IN	: in ALU_INPUT;
		R			: out STD_LOGIC_VECTOR(N-1 downto 0);
		FLAGS		: out ALU_FLAGS
	);
	end component alu;
	
	component CONTROL_UNIT is
	port(
		opcode : in std_logic_vector (5 downto 0);
		RegDst : out std_logic;
		RegWrite : out std_logic;
		ALUsrc : out std_logic;
		ALUop : out std_logic_vector (1 downto 0);
		Branch : out std_logic;
		MemWrite : out std_logic;
		MemToReg : out std_logic;
		Jump		: out std_logic;
		Stall 	: out std_logic
	);
	end component CONTROL_UNIT;
		
	component ALU_CTRL is
	port(
		ALU_Func : in std_logic_vector(5 downto 0);
		ALU_Ctrl : in std_logic_vector(1 downto 0);
		ALU_Op	: out alu_input
	);
	end component ALU_CTRL;
	
	component SignExtend is
		port(
		signExtendIn : in std_logic_vector(15 downto 0);
		signExtendOut : out std_logic_vector(31 downto 0)
	);
	
	end component SignExtend;
		
	signal read_data_1 : STD_LOGIC_VECTOR(31 downto 0);
	signal read_data_2 : STD_LOGIC_VECTOR(31 downto 0);
	signal alu_result : STD_LOGIC_VECTOR(31 downto 0);

	
	-- MUXRESULTAT OG KONTROLLSIGNAL
	signal res_ALUSrc : STD_LOGIC_VECTOR(31 downto 0);
	signal res_RegDst : STD_LOGIC_VECTOR(4 downto 0);
	signal res_MemToReg: STD_LOGIC_VECTOR(31 downto 0);
	signal res_Branch: STD_LOGIC_VECTOR(31 downto 0);
	signal res_SignExtended : STD_LOGIC_VECTOR(31 downto 0);

	signal res_ALUCtrl : ALU_INPUT;
	signal res_Jump		: STD_LOGIC_VECTOR (31 downto 0);
	
	signal ctrl_ALUSrc	: STD_LOGIC;
	signal ctrl_RegDst	: STD_LOGIC;
	signal ctrl_RegWrite : STD_LOGIC;
	signal ctrl_MemToReg : STD_LOGIC;
	signal ctrl_MemWrite	: STD_LOGIC;
	signal ctrl_Branch	: STD_LOGIC;
	signal ctrl_ALUCtrl	: STD_LOGIC_VECTOR ( 1 downto 0);
	signal ctrl_Jump		: STD_LOGIC;
	signal ctrl_Stall 	: STD_LOGIC;
	
	signal RegWrite		: STD_LOGIC;
	
	signal pc_current : STD_LOGIC_VECTOR(31 downto 0);
	signal pc_next : STD_LOGIC_VECTOR(31 downto 0);

	signal ALUFlags : ALU_FLAGS;
	
	signal jump_address	: STD_LOGIC_VECTOR (31 downto 0);
	
	type state is (fetch, execute, stall);
	signal current_state, next_state:  state;
	
begin

	

	reg_file : REGISTER_FILE
	port map(
		CLK		=> clk,
		RESET 	=> reset,		
		RW		=> RegWrite, 
		RS_ADDR => imem_data_in(25 downto 21),
		RT_ADDR => imem_data_in(20 downto 16),
		RD_ADDR => res_RegDst,
		WRITE_DATA => res_MemToReg,
		RS => read_data_1,
		RT => read_data_2
	);
	
	alu_impl : alu
	port map(
		X => read_data_1,
		Y => res_ALUSrc,
		R => alu_result,
		ALU_IN => res_ALUCtrl,
		FLAGS => ALUFlags
	);
	
	control : CONTROL_UNIT
	port map(
		opcode  	=> 	imem_data_in(31 downto 26),
		RegDst 	=>		ctrl_RegDst,
		RegWrite => 	ctrl_RegWrite,
		ALUsrc 	=> 	ctrl_ALUsrc,
		ALUop 	=> 	ctrl_ALUCtrl,
		Branch 	=> 	ctrl_Branch,
		MemWrite => 	ctrl_MemWrite,
		MemToReg => 	ctrl_MemToReg,
		Jump		=> 	ctrl_Jump,
		Stall 	=> 	ctrl_Stall
	);
	
	alu_ctrl_unit : ALU_CTRL
	port map(
		ALU_Func	=> imem_data_in(5 downto 0),
		ALU_Ctrl	=> ctrl_ALUCtrl,
		ALU_Op	=> res_ALUCtrl
	);
	

	signExtender : SignExtend
	port map(
		signExtendIn => imem_data_in(15 downto 0),
		signExtendOut => res_signExtended
	);

------------------
--  PROSESSER   --
------------------

state_transition : process( clk, processor_enable)
	begin
		if processor_enable = '0' then
			current_state <= fetch;
			pc_current <= ZERO32b;
		elsif rising_edge(clk) then
			current_state <= next_state;
			pc_current <= pc_next;
		end if;
	end process;

	state_machine: process( current_state, ctrl_stall, pc_next)
	begin
		case current_state is
			when fetch =>
				next_state <= execute;
			when execute =>
				if ctrl_stall = '1' then
					next_state <= stall;
				else
					next_state <= fetch;

				end if;
			when stall =>
				next_state <= fetch;
		end case;
	end process;
	
	pc_set : process ( clk, current_state, res_Branch, pc_current)
	begin
		if rising_edge ( clk ) then
			if current_state = fetch then
				pc_next <= res_Jump;
			end if;
		end if;
	end process;

	pc_branch : process ( ctrl_Branch, pc_current, res_signExtended, ALUflags )
	begin
		if ctrl_Branch = '1' and ALUflags.Zero = '1' then
			res_branch <= pc_current + res_signExtended + 1;
		else
			res_branch <= pc_current + 1;
		end if;
	end process;
	
	pc_jump : process ( ctrl_Jump, res_Branch, jump_address) 
	begin 
		if ctrl_Jump = '1' then
			res_Jump <= jump_address;
		else
			res_Jump <= res_branch;
		end if;
	end process;

	clr_write_signal : process ( ctrl_RegWrite, ctrl_MemWrite, current_state)
	begin
		if current_state = execute then
			RegWrite <= ctrl_RegWrite;
			dmem_write_enable <= ctrl_MemWrite;
		else 
			RegWrite <= '0';
			dmem_write_enable <= '0';
		end if;
	end process;
	
	concat_jump_address : process ( imem_data_in, pc_current )
	begin
		jump_address <= pc_current ( 31 downto 26 ) & imem_data_in ( 25 downto 0);
	end process;
	
	connect_pc_to_instructionmemory : process( pc_current)
	begin
		imem_address <= pc_current;
	end process;
	
	mux_RegDst : process(imem_data_in, ctrl_RegDst)
	begin
		if ctrl_RegDst = '0' then
			res_RegDst<= imem_data_in(20 downto 16);
		else
			res_RegDst <= imem_data_in(15 downto 11);
		end if;
	end process;
	
	mux_ALUSrc : process(ctrl_ALUSrc, res_SignExtended, read_data_2)
	begin
		if ctrl_ALUSrc = '0' then
			res_ALUSrc <= read_data_2;
		else
			res_ALUSrc <= res_SignExtended;
		end if;
	end process;
	
	mux_MemToReg : process(dmem_data_in, alu_result, ctrl_MemToReg)
	begin
		if ctrl_MemToReg = '0' then
			res_MemToReg <= alu_result;
		else
			res_MemToReg <= dmem_data_in;
		end if;
	end process;
	
	process_alu_result : process(alu_result, read_data_2)
	begin
			dmem_address <= alu_result;	
			dmem_address_wr <= alu_result;
			dmem_data_out <= read_data_2;
	end process;
	

	
end Behavioral;